home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / mail / Mutt089src.lha / Mutt-0.89i-AMIGA / src / init.c < prev    next >
C/C++ Source or Header  |  1998-01-28  |  34KB  |  1,517 lines

  1. /*
  2.  * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
  3.  * 
  4.  *     This program is free software; you can redistribute it and/or modify
  5.  *     it under the terms of the GNU General Public License as published by
  6.  *     the Free Software Foundation; either version 2 of the License, or
  7.  *     (at your option) any later version.
  8.  * 
  9.  *     This program is distributed in the hope that it will be useful,
  10.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *     GNU General Public License for more details.
  13.  * 
  14.  *     You should have received a copy of the GNU General Public License
  15.  *     along with this program; if not, write to the Free Software
  16.  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */ 
  18.  
  19. #include "mutt.h"
  20. #include "mutt_curses.h"
  21. #include "mutt_regex.h"
  22. #ifdef _PGPPATH
  23. #include "pgp.h"
  24. #endif
  25. #include "mx.h"
  26. #include "init.h"
  27. #include "mailbox.h"
  28.  
  29. #include <pwd.h>
  30. #include <ctype.h>
  31. #include <stdlib.h>
  32. #include <unistd.h>
  33. #include <string.h>
  34. #include <sys/utsname.h>
  35. #include <errno.h>
  36. #include <sys/wait.h>
  37.  
  38. #ifdef AMIGA
  39. # include "getenv.c"    /* getenv of ixemul.library is buggy */
  40. #endif
  41.  
  42. void set_quadoption (int opt, int flag)
  43. {
  44.   QuadOptions &= ~(0x3 << (2 * opt)); /* first clear the bits */
  45.   QuadOptions |= (flag & 0x3) << (2 * opt); /* now set them */
  46. }
  47.  
  48. int quadoption (int opt)
  49. {
  50.   return ((QuadOptions >> (opt * 2)) & 0x3);
  51. }
  52.  
  53. int query_quadoption (int opt, const char *prompt)
  54. {
  55.   int v = quadoption (opt);
  56.  
  57.   switch (v)
  58.   {
  59.     case M_YES:
  60.     case M_NO:
  61.       return (v);
  62.  
  63.     default:
  64.       v = mutt_yesorno (prompt, (v == M_ASKYES));
  65.       CLEARLINE (LINES - 1);
  66.       return (v);
  67.   }
  68.  
  69.   /* not reached */
  70. }
  71.  
  72. /* given the variable ``s'', return the index into the rc_vars array which
  73.  * matches, or -1 if the variable is not found.
  74.  */
  75. int mutt_option_index (char *s)
  76. {
  77.   int i;
  78.  
  79.   for (i=0; MuttVars[i].option; i++)
  80.     if (strcmp (s, MuttVars[i].option) == 0)
  81.       return (i);
  82.   return (-1);
  83. }
  84.  
  85. void mutt_add_to_list (LIST **list, const char *s)
  86. {
  87.   LIST *t, *last = NULL;
  88.   char buf[SHORT_STRING];
  89.   char expn[LONG_STRING];
  90.  
  91.   do
  92.   {
  93.     s = mutt_extract_token (buf, sizeof (buf), s, expn, sizeof (expn), 0);
  94.  
  95.     /* check to make sure the item is not already on this list */
  96.     for (last = *list; last; last = last->next)
  97.     {
  98.       if (strcasecmp (buf, last->data) == 0)
  99.       {
  100.     /* already on the list, so just ignore it */
  101.     last = NULL;
  102.     break;
  103.       }
  104.       if (!last->next)
  105.     break;
  106.     }
  107.  
  108.     if (!*list || last)
  109.     {
  110.       t = (LIST *) safe_calloc (1, sizeof (LIST));
  111.       t->data = safe_strdup (buf);
  112.  
  113.       if (last)
  114.       {
  115.     last->next = t;
  116.     last = last->next;
  117.       }
  118.       else
  119.     *list = last = t;
  120.     }
  121.   }
  122.   while (s);
  123. }
  124.  
  125. static void remove_from_list (LIST **l, const char *s)
  126. {
  127.   LIST *p, *last = NULL;
  128.   char buf[SHORT_STRING];
  129.   char expn[LONG_STRING];
  130.  
  131.   do
  132.   {
  133.     s = mutt_extract_token (buf, sizeof (buf), s, expn, sizeof (expn), 0);
  134.  
  135.     if (strcmp ("*", buf) == 0)
  136.       mutt_free_list (l);    /* ``unCMD *'' means delete all current entries */
  137.     else
  138.     {
  139.       p = *l;
  140.       last = NULL;
  141.       while (p)
  142.       {
  143.     if (strcasecmp (buf, p->data) == 0)
  144.     {
  145.       safe_free ((void **) &p->data);
  146.       if (last)
  147.         last->next = p->next;
  148.       else
  149.         (*l) = p->next;
  150.       safe_free ((void **) &p);
  151.     }
  152.     else
  153.     {
  154.       last = p;
  155.       p = p->next;
  156.     }
  157.       }
  158.     }
  159.   }
  160.   while (s);
  161. }
  162.  
  163. static int parse_unignore (const char *s, void *data, char *err, size_t errlen)
  164. {
  165.   mutt_add_to_list (&UnIgnore, s);
  166.   remove_from_list (&Ignore, s);
  167.   return 0;
  168. }
  169.  
  170. static int parse_ignore (const char *s, void *data, char *err, size_t errlen)
  171. {
  172.   mutt_add_to_list (&Ignore, s);
  173.   remove_from_list (&UnIgnore, s);
  174.   return 0;
  175. }
  176.  
  177. static int parse_list (const char *s, void *data, char *err, size_t errlen)
  178. {
  179.   mutt_add_to_list ((LIST **) data, s);
  180.   return 0;
  181. }
  182.  
  183. static int
  184. parse_unlist (const char *s, void *data, char *err, size_t errlen)
  185. {
  186.   remove_from_list ((LIST **) data, s);
  187.   return 0;
  188. }
  189.  
  190. static int parse_unalias (const char *s, void *data, char *err, size_t errlen)
  191. {
  192.   ALIAS *tmp, *last = NULL;
  193.   char buf[SHORT_STRING];
  194.   char expn[LONG_STRING];
  195.  
  196.   do
  197.   {
  198.     s = mutt_extract_token (buf, sizeof (buf), s, expn, sizeof (expn), 0);
  199.  
  200.     tmp = Aliases;
  201.     for (tmp = Aliases; tmp; tmp = tmp->next)
  202.     {
  203.       if (strcasecmp (buf, tmp->name) == 0)
  204.       {
  205.     if (last)
  206.       last->next = tmp->next;
  207.     else
  208.       Aliases = tmp->next;
  209.     tmp->next = NULL;
  210.     mutt_free_alias (&tmp);
  211.     break;
  212.       }
  213.       last = tmp;
  214.     }
  215.   }
  216.   while (s);
  217.   return 0;
  218. }
  219.  
  220. static int parse_alias (const char *s, void *data, char *errmsg, size_t errlen)
  221. {
  222.   ALIAS *tmp = Aliases;
  223.   ALIAS *last = NULL;
  224.   const char *p;
  225.   size_t len;
  226.   char buf[HUGE_STRING];
  227.   char expn[LONG_STRING];
  228.  
  229.   if ((p = strpbrk (s, " \t")) == NULL)
  230.   {
  231.     strfcpy (errmsg, "alias has no address", errlen);
  232.     return (-1);
  233.   }
  234.  
  235.   len = p - s;
  236.  
  237.   /* check to see if an alias with this name already exists */
  238.   for (; tmp; tmp = tmp->next)
  239.   {
  240.     if (strncasecmp (tmp->name, s, len) == 0 && *(tmp->name + len) == 0)
  241.       break;
  242.     last = tmp;
  243.   }
  244.  
  245.   if (!tmp)
  246.   {
  247.     /* create a new alias */
  248.     tmp = (ALIAS *) safe_calloc (1, sizeof (ALIAS));
  249.     tmp->name = safe_malloc (len + 1);
  250.     memcpy (tmp->name, s, len);
  251.     tmp->name[len] = 0;
  252.   }
  253.   else
  254.   {
  255.     /* override the previous value */
  256.     mutt_free_address (&tmp->addr);
  257.   }
  258.  
  259.   mutt_extract_token (buf, sizeof (buf), p, expn, sizeof (expn), M_QUOTE | M_SPACE);
  260.  
  261.   rfc822_parse_adrlist (&tmp->addr, buf, "@");
  262.  
  263.   if (last)
  264.     last->next = tmp;
  265.   else
  266.     Aliases = tmp;
  267.  
  268.   return 0;
  269. }
  270.  
  271. static int parse_unmy_hdr (const char *s, void *data, char *err, size_t errlen)
  272. {
  273.   LIST *last = NULL;
  274.   LIST *tmp = UserHeader;
  275.   LIST *ptr;
  276.   char buf[SHORT_STRING];
  277.   char expn[LONG_STRING];
  278.   size_t l;
  279.  
  280.   do
  281.   {
  282.     s = mutt_extract_token (buf, sizeof (buf), s, expn, sizeof (expn), 0);
  283.  
  284.     if (strcmp ("*", buf) == 0)
  285.       mutt_free_list (&UserHeader);
  286.     else
  287.     {
  288.       tmp = UserHeader;
  289.       last = NULL;
  290.  
  291.       l = strlen (buf);
  292.       if (buf[l - 1] == ':')
  293.     l--;
  294.  
  295.       while (tmp)
  296.       {
  297.     if (strncasecmp (buf, tmp->data, l) == 0 && tmp->data[l] == ':')
  298.     {
  299.       ptr = tmp;
  300.       if (last)
  301.         last->next = tmp->next;
  302.       else
  303.         UserHeader = tmp->next;
  304.       tmp = tmp->next;
  305.       ptr->next = NULL;
  306.       mutt_free_list (&ptr);
  307.     }
  308.     else
  309.     {
  310.       last = tmp;
  311.       tmp = tmp->next;
  312.     }
  313.       }
  314.     }
  315.   }
  316.   while (s);
  317.   return 0;
  318. }
  319.  
  320. static int parse_my_hdr (const char *s, void *data, char *errmsg, size_t errlen)
  321. {
  322.   LIST *tmp;
  323.   size_t keylen;
  324.   char *p;
  325.   char buf[LONG_STRING];
  326.   char expn[LONG_STRING];
  327.  
  328.   mutt_extract_token (buf, sizeof (buf), s, expn, sizeof (expn), M_SPACE | M_QUOTE);
  329.  
  330.   if ((p = strpbrk (buf, ": \t")) == NULL || *p != ':')
  331.   {
  332.     strfcpy (errmsg, "invalid header field", errlen);
  333.     return (-1);
  334.   }
  335.   keylen = p - buf + 1;
  336.  
  337.   p++;
  338.   SKIPWS (p);
  339.   if (!*p)
  340.   {
  341.     snprintf (errmsg, errlen, "ignoring empty header field: %s", s);
  342.     return (-1);
  343.   }
  344.  
  345.   if (UserHeader)
  346.   {
  347.     for (tmp = UserHeader; ; tmp = tmp->next)
  348.     {
  349.       /* see if there is already a field by this name */
  350.       if (strncasecmp (buf, tmp->data, keylen) == 0)
  351.       {
  352.     /* replace the old value */
  353.     safe_free ((void **) &tmp->data);
  354.     tmp->data = safe_strdup (buf);
  355.     return 0;
  356.       }
  357.  
  358.       if (!tmp->next)
  359.     break;
  360.     }
  361.  
  362.     tmp->next = mutt_new_list ();
  363.     tmp = tmp->next;
  364.   }
  365.   else
  366.   {
  367.     tmp = mutt_new_list ();
  368.     UserHeader = tmp;
  369.   }
  370.  
  371.   tmp->data = safe_strdup (buf);
  372.  
  373.   return 0;
  374. }
  375.  
  376. static int parse_sort (short *val, const char *s, char *err, size_t errlen)
  377. {
  378.   int i, flags = 0;
  379.  
  380.   if (strncmp ("reverse-", s, 8) == 0)
  381.   {
  382.     s += 8;
  383.     flags = SORT_REVERSE;
  384.   }
  385.   
  386.   if (strncmp ("last-", s, 5) == 0)
  387.   {
  388.     s += 5;
  389.     flags |= SORT_LAST;
  390.   }
  391.  
  392.   if ((i = mutt_getvaluebyname (s, SortMethods)) == -1)
  393.   {
  394.     snprintf (err, errlen, "%s: unknown sorting method", s);
  395.     return (-1);
  396.   }
  397.  
  398.   *val = i | flags;
  399.  
  400.   return 0;
  401. }
  402.  
  403. /* flags
  404.  *    M_EQUAL        '=' is a terminator
  405.  *    M_CONDENSE    condense ^(char) runs
  406.  *    M_SPACE        don't treat whitespace as a terminator
  407.  *    M_QUOTE        don't interpret quotes
  408.  *    M_BACKSLASH    don't interpret the `\'